Flattens an Observable-of-Observables.
換個說法,就是將接下來我會陸續到一堆
observable
,每接收到一個observable
,我就將他扁平化(flatten)
。
clicked
,就是我們接收回來的值,很直覺,對吧!click$.pipe(
map(() => 'clicked')
).subscribe(console.log);
我們將上面例子的字串,改為observable
,也就是我會接收到一個一個等待訂閱的observable
,那該怎麼進行呢?
設計回傳的observable
:
使用
interval+take
讀取3秒
將這些回傳的observable
一一的訂閱
// case1: can work but ugly code
let num = 0;
const timer$ = interval(1000).pipe(take(3)); //<-- 建置一個讀取3秒的observable
click$
.pipe(
tap(() => { //<-- 加入tap顯示click的次數
num += 1;
console.log('click-', num);
}),
map(() => timer$) //<-- 回傳timer$
)
.subscribe(
(obs) => obs.subscribe(console.log) //<-- 接收到observable,訂閱
);
timer$
,在第一層的訂閱接收到後,在裡面的next
進行再訂閱,你就會看到timer$
就會執行0->1->2
。click2~4 對應的timer$
就依序被觸發0->1->2
。click7
的timer$
會先進行計數,然後中間click8
的點擊發生,故會晚一步計數。如果未來接收的
observable
還會回傳更多的observable
,那豈不是要寫出波動拳程式了。
mergeAll
給他用下去!import { fromEvent, interval } from 'rxjs';
import { map, take, tap, mergeAll } from 'rxjs/operators';
const click$ = fromEvent(document, 'click');
// case2: mergeAll
let num = 0;
const timer$ = interval(1000).pipe(take(3)); //<-- 建置一個讀取3秒的observable
click$
.pipe(
tap(() => {
num += 1;
console.log('click-', num);
}),
map(() => timer$),
mergeAll()
)
.subscribe(console.log);
import { fromEvent, interval } from 'rxjs';
import { mergeMap, map, take, tap, mergeAll } from 'rxjs/operators';
const click$ = fromEvent(document, 'click');
// case2: mergeAll
let num = 0;
const timer$ = interval(1000).pipe(take(3)); //<-- 建置一個讀取3秒的observable
click$
.pipe(
tap(() => {
num += 1;
console.log('click-', num);
}),
// map(() => timer$),
// mergeAll()
mergeMap(() => timer$) //<-- mergeMap: 取代上面兩行
)
.subscribe(console.log);
mergeMap
= map(()=>observable)
+mergeAll()
。observable
,要一一的訂閱不是一個好的寫法,這時請服用mergeAll
mergeAll()
之前有用map
,可以用mergeMap
,讓寫法更俐落!呼~第26天順利達標,距離目標還剩下4天,GOGOGO~~~!!